package com.epk.pic.controller;

import com.epk.pic.controller.base.BaseController;
import com.epk.pic.mapper.PicMapper;
import com.epk.pic.mapper.TargetMapper;
import com.epk.pic.po.PicContents;
import com.epk.pic.po.PicInfoMain;
import com.epk.pic.po.PicTargetMain;
import com.epk.pic.po.PicTargets;
import com.epk.pic.service.PicService;
import com.epk.pic.vo.PicInfoVo;
import com.epk.pic.vo.PicQueryVo;
import com.epk.pic.vo.base.ApiResponse;
import com.epk.pic.vo.base.TableDataInfo;
import com.github.pagehelper.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;


@RestController
@RequestMapping("/item")
public class ItemController extends BaseController {
    @Autowired
    private PicMapper picMapper;
    @Autowired
    private PicService picService;
    @Autowired
    private TargetMapper targetMapper;

    @GetMapping("/info/{id}")
    public ApiResponse<PicInfoVo> info(@PathVariable Long id) {
        PicInfoMain picInfoMain = picMapper.selectPicMainById(id);
        PicInfoVo picInfoVo = new PicInfoVo();
        BeanUtils.copyProperties(picInfoMain, picInfoVo);
        List<PicTargets> picTargets = targetMapper.selectTargetByMaimId(id);
        HashMap<String, List<String>> targetsMap = new HashMap<>();
        picTargets.forEach(t -> extractedTarget(targetsMap, t));
        List<PicContents> picContents = picMapper.selectContentsByMaimIdAndType(id, "00");
        if (picContents.size() > 0) {
            picInfoVo.setMainPic(picContents.get(0).getFilePath());
        }
        picInfoVo.setTargetsMap(targetsMap);
        picInfoVo.setPicContents(picContents);
        picMapper.addClick(id);
        return ApiResponse.succ(picInfoVo);
    }

    @PostMapping("/delete/{id}")
    @Transactional
    public ApiResponse<Void> delete(@PathVariable Long id) {
        picMapper.deleteMainById(id);
        targetMapper.deleteTargetByMaimId(id);
        return ApiResponse.succ();
    }

    @GetMapping("/pic/{id}")
    public void pic(@PathVariable Long id, HttpServletResponse response) throws IOException {
        PicContents picContents = picMapper.selectContentsById(id);
        File file = new File(picContents.getFilePath());
        String suffix = StringUtils.getFilenameExtension(file.getName());
        BufferedImage bufferedImage = ImageIO.read(file);
        response.setContentType("image/jpeg");
        ImageIO.write(bufferedImage, suffix == null ? "jpg" : suffix, response.getOutputStream());
    }

    @PostMapping(value = "/upload", consumes = {"multipart/form-data"})
    @Transactional
    public ApiResponse<Void> upload(@RequestPart("uploadVo") PicInfoVo uploadVo, MultipartRequest request) {
        Long picMainId = picMapper.nextVal("picMainId");
        try {
            Map<String, List<String>> map = uploadVo.getTargetsMap();
            if (map != null) {
                for (String s : map.keySet()) {
                    PicTargetMain picTargetMain = targetMapper.selectTargetMain(s);
                    if (picTargetMain == null) {
                        throw new RuntimeException("标签" + s + "未配置！");
                    }
                    if (picTargetMain.getTargetLevel() < 3) {
                        throw new RuntimeException("标签" + picTargetMain.getTargetName() + "不允许上传！");
                    }
                    for (String s1 : map.get(s)) {
                        PicTargets picTargets = new PicTargets();
                        picTargets.setPicMainID(picMainId);
                        picTargets.setTargetName(s);
                        picTargets.setTargetValue(s1);
                        targetMapper.savePicTargets(picTargets);
                    }
                }
            }

            Iterator<String> fileNames = request.getFileNames();
            while (fileNames.hasNext()) {
                String next = fileNames.next();
                List<MultipartFile> files = request.getFiles(next);
                for (MultipartFile multipartFile : files) {
                    String contentType = multipartFile.getContentType();
                    if (contentType == null || !contentType.startsWith("image")) {
                        continue;
                    }
                    PicContents picContent = picService.uploadFIle(multipartFile);
                    if (next.equals("mainPic")) {
                        picContent.setPicType("00");
                    } else {
                        picContent.setPicType("01");
                    }
                    picContent.setPicMainID(picMainId);
                    picMapper.savePicContents(picContent);
                }
            }

            uploadVo.setId(picMainId);
            picMapper.savePicInfoMain(uploadVo);
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                e.printStackTrace();
                return ApiResponse.err(e.getMessage());
            } else {
                throw new RuntimeException(e);
            }
        }
        return ApiResponse.succ();
    }

    @PostMapping("/query")
    public TableDataInfo<PicInfoVo> query(@RequestBody PicQueryVo queryVo) throws IOException {
        List<PicInfoVo> rows = new ArrayList<>();
        Map<String, String> targets = queryVo.getTargetsMap();
        Integer searchSub = queryVo.getSearchSub();
        searchSub = searchSub == null || searchSub == 0 ? 1 : searchSub < 0 ? 999 : searchSub;
        List<String> targetGroup = picService.getTargetGroup(targets, searchSub);
        queryVo.setTargetGroup(targetGroup);
        Page<?> objects = super.startPage(queryVo);
        List<PicInfoMain> picInfoMains = picMapper.selectByQueryVo(queryVo);
        for (PicInfoMain infoMain : picInfoMains) {
            PicInfoVo picInfoVo = new PicInfoVo();
            BeanUtils.copyProperties(infoMain, picInfoVo);
            List<PicTargets> picTargets = targetMapper.selectTargetByMaimId(infoMain.getId());
            HashMap<String, List<String>> targetsMap = new HashMap<>();
            picTargets.forEach(t -> extractedTarget(targetsMap, t));
            List<PicContents> picContents = picMapper.selectContentsByMaimIdAndType(infoMain.getId(), "00");
            if (picContents.size() > 0) {
                picInfoVo.setMainPic(picContents.get(0).getFilePath());
            }
            picInfoVo.setTargetsMap(targetsMap);
            rows.add(picInfoVo);
        }
        return TableDataInfo.build(objects, rows);
    }

    private static void extractedTarget(HashMap<String, List<String>> targetsMap, PicTargets t) {
        List<String> w = targetsMap.get(t.getTargetName()) == null ? new ArrayList<>() : targetsMap.get(t.getTargetName());
        w.add(t.getTargetValue());
        targetsMap.put(t.getTargetName(), w);
    }

    @GetMapping({"/v/{tagValue}/{pageNo}", "/v/{tagValue}"})
    @Transactional
    public TableDataInfo<PicInfoVo> simpleV(@PathVariable String tagValue, @PathVariable(required = false) Integer pageNo) throws IOException {
        return this.simpleT("other", tagValue, pageNo);
    }

    @GetMapping({"/t/{tagName}/{tagValue}/{pageNo}","/t/{tagName}/{tagValue}"})
    @Transactional
    public TableDataInfo<PicInfoVo> simpleT(@PathVariable String tagName, @PathVariable String tagValue, @PathVariable(required = false) Integer pageNo) throws IOException {
        PicQueryVo picQueryVo = new PicQueryVo();
        picQueryVo.setPageNo(pageNo);
        Map<String, String> stringStringMap = new HashMap<>();
        stringStringMap.put(tagName, tagValue);
        picQueryVo.setTargetsRelate("or");
        picQueryVo.setTargetsMap(stringStringMap);
        return this.query(picQueryVo);
    }

    @GetMapping({"/s/{title}/{pageNo}","/s/{title}"})
    @Transactional
    public TableDataInfo<PicInfoVo> simpleS(@PathVariable String title, @PathVariable(required = false) Integer pageNo) throws IOException {
        PicQueryVo picQueryVo = new PicQueryVo();
        picQueryVo.setPageNo(pageNo);
        picQueryVo.setTitle(title);
        return this.query(picQueryVo);
    }

    @GetMapping({"/a/{auth}/{pageNo}","/a/{auth}"})
    @Transactional
    public TableDataInfo<PicInfoVo> simpleA(@PathVariable String auth, @PathVariable(required = false) Integer pageNo) throws IOException {
        PicQueryVo picQueryVo = new PicQueryVo();
        picQueryVo.setPageNo(pageNo);
        picQueryVo.setAuth(auth);
        return this.query(picQueryVo);
    }

}